﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HaumDisplay
{
    public class HaumPolygon : HaumShape
    {
        /// <summary>
        /// 路径
        /// </summary>
        public List<PointF> contours;

        internal bool isConnectd;

        internal Pen pen;

        /// <summary>
        /// 反色
        /// </summary>
        internal Color invertColor;

        /// <summary>
        /// 是否选中
        /// </summary>
        internal bool isSelect;

        /// <summary>
        /// 是否拖动点
        /// </summary>
        internal bool isDroging;

        /// <summary>
        /// 路径点索引
        /// </summary>
        internal int contourIndex;

        /// <summary>
        /// 开始绘制
        /// </summary>
        internal bool startGraphic;

        public HaumPolygon(Color color, int borderSize = 1)
        {
            this.contours = new List<PointF>();
            this.isConnectd = false;
            this.pen = new Pen(color, borderSize);
            this.invertColor = Color.FromArgb(color.R / 2, color.G / 2, color.B / 2);
            this.isSelect = false;
            this.contourIndex = -1;
            this.startGraphic = false;
        }

        /// <summary>
        /// 修改所有路径
        /// </summary>
        /// <param name="curPoint"></param>
        public void ContoursOffset(float offsetX, float offsetY)
        {
            for (int i = 0; i < contours.Count; i++)
            {
                contours[i] = new PointF(contours[i].X +offsetX, contours[i].Y + offsetY);
            }
        }

        public void PathOffset(PointF offset)
        {

            if (contourIndex == 0 && this.isConnectd)
            {
                int linkIndex = contours.Count - 1;
                contours[0] = new PointF(contours[0].X + offset.X, contours[0].Y + offset.Y);
                contours[linkIndex] = new PointF(contours[linkIndex].X + offset.X, contours[linkIndex].Y + offset.Y);
            }
            else
            {
                contours[contourIndex] = new PointF(contours[contourIndex].X + offset.X, contours[contourIndex].Y + offset.Y);
            }
        }

        /// <summary>
        /// 获取中心点
        /// </summary>
        /// <returns></returns>
        public PointF GetCenter()
        {
            if (contours.Count > 0)
            {
                float minX = contours.Min(p => p.X);
                float maxX = contours.Max(p => p.X);
                float minY = contours.Min(p => p.Y);
                float maxY = contours.Max(p => p.Y);
                return new PointF(minX + (maxX - minX) / 2, minY + (maxY - minY) / 2);
            }
            else
            {
                return new PointF(0, 0);
            }
        }

        /// <summary>
        /// 获取宽度
        /// </summary>
        /// <returns></returns>
        public float GetWidth()
        {
            float minX = contours.Min(p => p.X);
            float maxX = contours.Max(p => p.X);
            return maxX - minX;
        }

        /// <summary>
        /// 获取高度
        /// </summary>
        /// <returns></returns>
        public float GetHeight()
        {
            float minY = contours.Min(p => p.Y);
            float maxY = contours.Max(p => p.Y);

            return maxY - minY;
        }

        /// <summary>
        /// 获取面积
        /// </summary>
        /// <returns></returns>
        public double GetArea()
        {
            if (contours.Count < 3)
            {
                return 0;
            }
            double area = 0;
            for (int i = 0; i < contours.Count; i++)
            {
                //鞋带公式
                int j = (i + 1) % contours.Count;
                area += contours[i].X * contours[j].Y - contours[j].X * contours[i].Y;
            }
            return Math.Abs(area) / 2;
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("多边形路径:");
            for (int i = 0; i < contours.Count; i++)
            {
                sb.Append($"[{contours[i].X},{contours[i].Y}]");
            }
            sb.Append($"-中心点:[{this.GetCenter()}]-面积:[{this.GetArea().ToString("f3")}]");
            return sb.ToString();
        }


        public override void Graphic(Graphics g, GraphicHelper myGraphic)
        {
            g.SmoothingMode = SmoothingMode.HighQuality;
            //绘制路径
            List<PointF> cs = Tools.ImageTransScreenPointF(this.contours, myGraphic.scale, myGraphic.offset);
            if (cs.Count >= 2)
            {
                g.DrawLines(this.pen, cs.ToArray());
            }

            //绘制中心小十字
            //获取圆心像素坐标 转换成控件坐标
            PointF center = Tools.ImageTransScreenPointF(this.GetCenter(), myGraphic.scale, myGraphic.offset);
            //根据中心坐标拟合两条垂直线
            // 绘制垂直的线（中心点上下各 3 像素）
            g.DrawLine(this.pen, center.X, center.Y - 5, center.X, center.Y + 5);
            // 绘制水平的线（中心点左右各 3 像素）
            g.DrawLine(this.pen, center.X - 5, center.Y, center.X + 5, center.Y);

            float r = this.pen.Width * 3;

            //所有路径点
            using (Brush contoursBrush = new SolidBrush(this.isSelect || this.isDroging ? this.invertColor : this.pen.Color))
            {
                foreach (PointF p in cs)
                {
                    //绘制拖动缩放点
                    g.FillEllipse(contoursBrush, p.X - (r / 2), p.Y - (r / 2), r, r);
                }

                if (this.isDroging)
                {
                    g.FillEllipse(contoursBrush, cs[this.contourIndex].X - (r / 2), cs[this.contourIndex].Y - (r / 2), r, r);
                }
            }
        }
    }
}
